#include <string>

using namespace std;

#define BUFFER_SIZE 1024

typedef int Int32;

struct ninteger;

class Integer {
public:
	static Integer *Zero, *One;

	Integer(const Int32 width, const bool isSigned);
	Integer(const Int32 width, const int value, const bool isSigned);
	Integer(const Int32 width, const string value, const bool isSigned);

	Int32 ToInt();
	void  ToBinaryString(char* buffer, const size_t bufsize);
  void  ToDecimalString(char* buffer, const size_t bufsize);
  void  ToHexadecimalString(char* buffer, const size_t bufsize);

	void ValueCopy(const Integer* value);
	static void GetRange(Integer** result, Integer* value, Int32 from, Int32 to);
	

	static void Negate(Integer** result, Integer* a);

	static void And(Integer** result, Integer* a, Integer* b);
	static void Or(Integer** result, Integer* a, Integer* b);
	static void Xor(Integer** result, Integer* a, Integer* b);
	static void Not(Integer** result, Integer* value);
	
	static void Add(Integer** result, Integer* a, Integer* b);
	static void Subtract(Integer** result, Integer* a, Integer* b);
	static void Multiply(Integer** result, Integer* a, Integer* b);
	static void Divide(Integer** result, Integer* a, Integer* b);
	
	static void ShiftLeft(Integer** result, Integer* value, Int32);
	static void ShiftRight(Integer** result, Integer* value, Int32);

  static void GetBit(Integer** result, Integer* value, Int32);

	bool Equals(const Integer* a);
	bool NotEquals(const Integer* a);
	bool GreaterThan(const Integer* a);
	bool GreaterThanOrEquals(const Integer* a);
	bool LessThan(const Integer* a);
	bool LessThanOrEquals(const Integer* a);

  // experimental operator overloads
	bool operator== (const Integer& a);
	bool operator!= (const Integer& a);

	friend bool operator== (const Integer& a, const Integer& b);
	friend bool operator!= (const Integer& a, const Integer& b);

private:
	ninteger* _integer;
};

